#include "../bsp.h"

#if defined (XPAR_XEMACPS_NUM_INSTANCES) || defined (XPAR_XAXIETHERNET_NUM_INSTANCES)
#if defined (UDP_COMMAND_SRV)

static struct udp_pcb *client_pcb = NULL;
static struct pbuf *pbuf_to_be_sent = NULL;
ip_addr_t target_addr;

extern FlashInfo Flash_Config_Table[28];
extern u32 FlashMake;
extern u32 FCTIndex;	/* Flash configuration table index */

uint8_t receivebuf[1500] = {0};
uint8_t send_buf[1500] = {0};
int receivelen = 0;
int sendlen = 0;
u8 cerrent_ch;

int32_t Status=0;
uint16_t msg_len=0;
uint16_t msg_cmd=0;
uint32_t msg_addr=0;
uint32_t msg_value=0;
uint8_t msg_ack=0;
uint16_t mem_len=0;

void print_udp_cmd_header(void)
{
    bsp_printf("%20s %6d\r\n", "UDP CMD", UDP_CMD_SVR_PORT);
}

static uint8_t checksum(uint8_t * ptr, int16_t cnt)
{
	int16_t i = 0;
	uint8_t calc=0;
	for(i=0;i<cnt;i++)
	{
		calc=calc + ptr[i];
	}

	return calc=~calc&0xff;
}

void msg_cmd_0x10(void)
{
	memcpy(&msg_addr,receivebuf+5,4);
	msg_value = Xil_In32(msg_addr); // don't use signed int, otherwise hardfail
	//mdata=htonl(mdata);
	sendlen=receivelen;
	memcpy(send_buf,receivebuf,receivelen);
	memcpy(send_buf+9,&msg_value,4);
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x11(void)
{
	memcpy(&msg_addr,receivebuf+5,4);
	memcpy(&msg_value,receivebuf+9,4);
	//msg_value=htonl(msg_value);
	//*(volatile unsigned int *)(msg_addr) = msg_value;
	Xil_Out32(msg_addr, msg_value);
	msg_value = Xil_In32(msg_addr); // don't use signed int, otherwise hardfail
	sendlen=receivelen;
	memcpy(send_buf,receivebuf,receivelen);
	memcpy(send_buf+9,&msg_value,4);
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x12(void)
{
	memcpy(&msg_addr,receivebuf+5,4);
	memcpy(&mem_len,receivebuf+9,4);
	sendlen=receivelen+mem_len*4;
	if(sendlen > ARRAY_SIZE(send_buf))
	{
		return;
	}
	memcpy(send_buf,receivebuf,receivelen);
	memcpy(send_buf+receivelen-1,(void*)msg_addr,mem_len*4);
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x13(void)
{
	memcpy(&msg_addr,receivebuf+5,4);
	memcpy(&mem_len,receivebuf+9,4);
	memcpy((void*)msg_addr,receivebuf+13,mem_len*4);
	if(mem_len*4 + 14 > ARRAY_SIZE(send_buf))
	{
		return;
	}
	sendlen=receivelen-mem_len*4;
	if(sendlen < 14)
	{
		return;
	}
	memcpy(send_buf,receivebuf,sendlen);
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x20(void)
{
	uint8_t addr;
	uint8_t ch;
	uint8_t len;
	uint8_t flag;
	uint16_t reg_addr;
	uint8_t data[256];
	ch =receivebuf[5];
	addr = receivebuf[6];
	len = receivebuf[7];
	reg_addr = (uint16_t)receivebuf[8] << 8 | receivebuf[9];
	flag = receivebuf[10];
	if(flag == 1)
	{
		Status = xgpio_i2c_reg8_continuous_read(ch,addr>>1,reg_addr,data,len,STRETCH_OFF);
	}
	else
	{
		Status = xgpio_i2c_reg16_continuous_read(ch,addr>>1,reg_addr,data,len,STRETCH_OFF);
	}

	memcpy(send_buf,receivebuf,5);
	memcpy(send_buf+5,&Status,1);
	memcpy(send_buf+6,data,len);
	sendlen = 6 + len+1;
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1); //
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x21(void)
{
	printf("recv ch\r\n");
	uint8_t addr;
	uint8_t ch;
	uint8_t value;
	uint8_t flag;
	uint16_t reg_addr;

	addr = receivebuf[6];
	ch =receivebuf[5];
	reg_addr = (uint16_t)receivebuf[7] << 8 | receivebuf[8];
	flag = receivebuf[9];
	value = receivebuf[11];
	if(flag == 1)
	{
		Status = xgpio_i2c_reg8_write(ch,addr>>1,reg_addr,value,STRETCH_OFF);
	}
	else
	{
		Status = xgpio_i2c_reg16_write(ch,addr>>1,reg_addr,value,STRETCH_OFF);
	}

	memcpy(send_buf,receivebuf,5);
	memcpy(send_buf+5,&Status,1);
	memcpy(send_buf+6,receivebuf+5,msg_len-5);
	sendlen = msg_len + 1;
	send_buf[sendlen-1] = checksum(send_buf,sendlen-1); //
	memcpy(send_buf,&sendlen,2);
}

void msg_cmd_0x40(void)
{
	uint16_t cmd_index;
	uint32_t msg_send;
	memcpy(&cmd_index,receivebuf+5,2);

	if(cmd_index==0)
	{
//			uint16_t major = __SW_VER_MAJOR__;
//			uint16_t minor = __SW_VER_MINOR__;
#if defined (XPAR_AXI_LITE_REG_NUM_INSTANCES) && (XPAR_AXI_LITE_REG_0_DEVICE_ID == 0)
		uint32_t ver = __HW_VER__;
#else
		uint32_t ver = 0;
#endif

//			msg_send = (uint32_t)(((uint32_t)major)<<16) + (uint32_t)minor;
		msg_send = ver;

		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,4);
		sendlen = 12;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==1)
	{
//			uint16_t major = __SW_VER_MAJOR__;
//			uint16_t minor = __SW_VER_MINOR__;
		uint32_t ver = __SW_VER__;
//			msg_send = (uint32_t)(((uint32_t)major)<<16) + (uint32_t)minor;
		msg_send = ver;

		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,4);
		sendlen = 12;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==2)
	{
//			uint16_t major = __SW_VER_MAJOR__;
//			uint16_t minor = __SW_VER_MINOR__;
		uint32_t ver = 0x00300000; // keep same as type==0 in qspi_update()
//			msg_send = (uint32_t)(((uint32_t)major)<<16) + (uint32_t)minor;
		msg_send = ver;

		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,4);
		sendlen = 12;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==3)
	{
//			uint16_t major = __SW_VER_MAJOR__;
//			uint16_t minor = __SW_VER_MINOR__;
		uint32_t ver = FlashMake;
		char *send_arr = NULL;
		if(FlashMake == MICRON_ID_BYTE0)
		{
			send_arr = "MICRON";
		}
		else if(FlashMake == SPANSION_ID_BYTE0)
		{
			send_arr = "SPANSION";
		}
		else if(FlashMake == WINBOND_ID_BYTE0)
		{
			send_arr = "WINBOND";
		}
		else if(FlashMake == MACRONIX_ID_BYTE0)
		{
			send_arr = "MACRONIX";
		}
		else if(FlashMake == ISSI_ID_BYTE0)
		{
			send_arr = "ISSI";
		}
//			msg_send = (uint32_t)(((uint32_t)major)<<16) + (uint32_t)minor;
//			msg_send = ver;
		bsp_printf("string = %s,len = %d\r\n",send_arr,strlen(send_arr));
		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,send_arr,strlen(send_arr));
		sendlen = 7+strlen(send_arr)+1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==4)
	{
//			uint16_t major = __SW_VER_MAJOR__;
//			uint16_t minor = __SW_VER_MINOR__;
		FlashInfo*flash_ptr=&Flash_Config_Table[FCTIndex];
		uint32_t ver = (flash_ptr->FlashDeviceSize)/1024;
//			msg_send = (uint32_t)(((uint32_t)major)<<16) + (uint32_t)minor;
		msg_send = ver;

		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,4);
		sendlen = 12;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==5)// cur_ch_get
	{
		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&cerrent_ch,1);
		sendlen = 9;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==6) //cur_ch_set
	{
		uint8_t var1;
		memcpy(&var1,receivebuf+7,1);
		cerrent_ch = var1;
		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,1);
		sendlen = 7 + 1 + 1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index == 7)
	{
		uint8_t var1;
		memcpy(&var1,receivebuf+7,1);
		reset_pl = var1;
		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,1);
		sendlen = 7 + 1 + 1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==10) // read global_config
	{
		memcpy(send_buf,receivebuf,7);
	//	memcpy(send_buf+7, &global_config, sizeof(config_Settings_t));
	//	sendlen = 7 + sizeof(config_Settings_t) + 1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==11) // save global_config
	{
		int32_t Status;
		uint8_t sendmsg;
	//	memcpy(&global_config,receivebuf+7,sizeof(config_Settings_t));
//			memcpy(&(global_config.frequency_Hz),receivebuf+29,sizeof(int64_t));
//			memcpy(&(global_config.agc_mode),receivebuf+37,1);
		// U34 choose port 0
//			I2cMux_Eeprom();
//		Status = saveconfig(&global_config);

		if(Status!=XST_SUCCESS)
		{
			sendmsg = 1;
		}
		else
		{
			sendmsg = 0;
		}

		memcpy(send_buf,receivebuf,7);
		memcpy(send_buf+7,&msg_send,1);
		sendlen = 7 + 1 + 1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
	if(cmd_index==12) // read default_config
	{
		memcpy(send_buf,receivebuf,7);
	//	memcpy(send_buf+7, &default_config, sizeof(config_Settings_t));
		//sendlen = 7 + sizeof(config_Settings_t) + 1;
		send_buf[sendlen-1] = checksum(send_buf,sendlen-1);
		memcpy(send_buf,&sendlen,2);
	}
}


void msg_cmd_0x80(void)
{
#if defined (UDP_VIDEO)
	if(receivebuf[6] == 0x00)  //Turn off the image display of the host computer
	{
	    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
	    {
	    	VdmaChannels[i].send_pic_start = 0;
	    	VdmaChannels[i].send_video_start = 0;
	    }
		xil_printf("close all video source\r\n");
	}
	else if( receivebuf[6] == 0x01)  //send picture
	{
		if(receivebuf[5] == 0x00)
		{
		    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
		    {
		    	VdmaChannels[i].send_pic_start = 0;
		    }
		}
		else if(receivebuf[5] == 0xff)
		{
		    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
		    {
		    	VdmaChannels[i].send_pic_start = 1;
		    }
		}
		else
		{
			if(receivebuf[5] > NUM_CHANNELS)
			{
				xil_printf("pic source cmd error\r\n");
			}
			else
			{
				VdmaChannels[receivebuf[5]-1].send_pic_start = 1;
			}
		}
	}
	else if(receivebuf[6] == 0x02)  //send video
	{
		if(receivebuf[5] == 0x00)
		{
		    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
		    {
		    	VdmaChannels[i].send_video_start = 0;
		    }
		}
		else if(receivebuf[5] == 0xff)
		{
		    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
		    {
		    	VdmaChannels[i].send_video_start = 1;
		    }
		}
		else
		{
			if(receivebuf[5] > NUM_CHANNELS)
			{
				xil_printf("video source cmd error\r\n");
			}
			else
			{
				VdmaChannels[receivebuf[5]-1].send_video_start = 1;
			}
		}
	}
	else if(receivebuf[6] == 0x03)  //switch video
	{
#if defined (XPAR_XAXIS_SWITCH_NUM_INSTANCES)
		if(receivebuf[5] == 0x00)
		{
			AxisSwitch(XPAR_AXIS_SWITCH_0_DEVICE_ID, &AxisSwitch0, 0, 0); //
		}
		else if(receivebuf[5] == 0x01)
		{
			AxisSwitch(XPAR_AXIS_SWITCH_0_DEVICE_ID, &AxisSwitch0, 1, 0); //
		}
		else if(receivebuf[5] == 0x02)
		{
			AxisSwitch(XPAR_AXIS_SWITCH_0_DEVICE_ID, &AxisSwitch0, 2, 0); //
		}
		else if(receivebuf[5] == 0x03)
		{
			AxisSwitch(XPAR_AXIS_SWITCH_0_DEVICE_ID, &AxisSwitch0, 3, 0); //
		}
		else
		{
			xil_printf("video source cmd error\r\n");
		}
#endif
	}
	else
	{
		xil_printf("video source cmd error\r\n");

	}
#endif
}


void udp_cmd_recv_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p,
		const ip_addr_t *addr, u16_t port)
{
    struct pbuf *pq;
	//receivelen = p->len;
	receivelen = p->tot_len;
	memset(receivebuf, 0, sizeof(receivebuf));
	memset(send_buf, 0, sizeof(send_buf));
	//memcpy(receivebuf,p->payload,p->len);
	pbuf_copy_partial(p, receivebuf, p->tot_len, 0);
    pbuf_free(p);

    upcb->remote_ip = *addr;
    upcb->remote_port = port;
    client_pcb = upcb;


//	xil_printf("%d.%d.%d.%d\r\n", ip4_addr1(addr), ip4_addr2(addr), ip4_addr3(addr), ip4_addr4(addr));
//	xil_printf("port  : %d\r\n",port);
//    xil_printf("receive data : %x\r\n",receivebuf[4]);
//    xil_printf("msg_cmd : %x\r\n",*(receivebuf+4));

    msg_len = 0;
    msg_cmd = 0;

    memcpy(&msg_len,receivebuf,2);
    memcpy(&msg_cmd,receivebuf+4,1);

    if(msg_cmd == 0x10)	// read mem addr
    {
    	msg_cmd_0x10();
    }
    else if(msg_cmd == 0x11)	// write mem addr
	{
    	msg_cmd_0x11();
	}
    else if(msg_cmd == 0x12)	// read mem bulk
	{
    	msg_cmd_0x12();
	}
    else if(msg_cmd == 0x13)	// write mem bulk
	{
    	msg_cmd_0x13();
	}
    else if(msg_cmd == 0x20)
	{
    	msg_cmd_0x20();
	}
    else if(msg_cmd == 0x21)
	{
    	msg_cmd_0x21();
	}
    else if(msg_cmd == 0x40) // variables get and set
    {
    	msg_cmd_0x40();
    }


    if(msg_cmd == 0x80)	// video control
	{
    	msg_cmd_0x80();
	}
    else
    {
	//    pq = pbuf_alloc(PBUF_TRANSPORT,sendlen,PBUF_POOL);
		pq = pbuf_alloc(PBUF_TRANSPORT, sendlen, PBUF_RAM);
		pbuf_take(pq,(char*)send_buf,sendlen);

		udp_connect(upcb, addr, port);
	#ifdef PRINT_REMOTE
		  bsp_printf("local %s port %d connected with ",
					inet_ntoa(echo_netif->ip_addr),
					echo_server_port);
		  bsp_printf("%s port %d\r\n", inet_ntoa(*addr),
				  port);
	#endif
		udp_send(upcb,pq);
	//    udp_sendto(upcb, pq, addr, port);
		udp_disconnect(upcb);
		pbuf_free(pq);
    }
}
/*
 * Create new pcb, bind pcb and port, set call back function
 */
int start_udp_cmd_application(void)
{
	struct udp_pcb *pcb;
	err_t err;

	/* Create a new UDP PCB structure  */
	pcb = udp_new();
	if (!pcb)
	{
		bsp_printf("Error creating PCB. Out of Memory\n\r");
		return -1;
	}

	/* Bind the upcb to the UDP_PORT port */
	/* Using IP_ANY_TYPE==IP_ADDR_ANY allow the upcb to be used by any local interface */
	err = udp_bind(pcb, IP_ADDR_ANY, UDP_CMD_SVR_PORT);
	if (err != ERR_OK)
	{
		xil_printf("UDP server: Unable to bind to port");
		bsp_printf("Unable to bind to port %d: err = %d\n\r", UDP_CMD_SVR_PORT, err);
		udp_remove(pcb);
		return -2;
	}

    /* Set a receive callback for the upcb */
	udp_recv(pcb, udp_cmd_recv_callback, NULL);
//	bsp_printf("UDP server started @ port %d\n\r", UDP_CMD_SVR_PORT);

//	IP4_ADDR(&target_addr, 192,168,1,77);

#if defined (UDP_VIDEO)
    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
    {
    	VdmaChannels[i].send_pic_start = 0;
    	VdmaChannels[i].send_video_start = 0;
    }
#endif

	return 0;
}

void transfer_udp_cmd_data(void)
{
	return;
}



#if defined (UDP_VIDEO)

packet_header packet_p;

/**
 * @brief 通用数据发送逻辑，处理图片或视频发送
 * @param channel 当前通道索引
 * @return 是否需要继续传输 (1 表示继续, 0 表示停止)
 */
int handle_channel_transfer(int channel)
{
    VdmaChannel *currentChannel = &VdmaChannels[channel];

    int sta;

    // 检查当前帧是否已发送完所有数据包
    if (currentChannel->pkg_cnt <= currentChannel->udp_send_times)
    {
        // 构造数据包头部
        packet_p.HEAD_ID    = HEADER_ID;
        packet_p.Channel_ID = currentChannel->channel_ID;
        packet_p.SEND_FLAG  = currentChannel->VIDEO_FLAG;
        packet_p.Width      = currentChannel->Width;
        packet_p.Height     = currentChannel->Height;
        packet_p.total      = currentChannel->FrameLength;
        packet_p.offset     = (currentChannel->pkg_cnt - 1) * currentChannel->UDP_IMG_PACKEG_SIZE;
        packet_p.picseq     = channel; // 通道的独立序列号
        packet_p.frameseq   = currentChannel->pkg_cnt;
        packet_p.framesize  = currentChannel->UDP_IMG_PACKEG_SIZE;

        // 刷新缓存
        Xil_DCacheInvalidateRange(
            (u32)(currentChannel->FrameBuffers[currentChannel->WriteOneFrameEnd] + packet_p.offset),
            currentChannel->UDP_IMG_PACKEG_SIZE);


        // 发送数据包
        sta = sendpic((u8 *)(currentChannel->FrameBuffers[currentChannel->WriteOneFrameEnd] + packet_p.offset),
                      currentChannel->UDP_IMG_PACKEG_SIZE);

        // 检查发送状态
        if (sta != 0)
        {
            DEBUG_PRINTF("Channel %d: sendpic error pkg_cnt:%d\r\n", channel, currentChannel->pkg_cnt);
            currentChannel->WriteOneFrameEnd = -1;
            currentChannel->pkg_cnt = 1;
            if (currentChannel->VIDEO_FLAG == SEND_PIC) // 图片传输失败后停止

            return -1; // 传输失败，停止
        }

        // 成功发送，增加计数
        currentChannel->pkg_cnt++;
    }
    else // 当前帧发送完成
    {
        if (currentChannel->VIDEO_FLAG == SEND_PIC) // 图片传输完成
        {
            xil_printf("Channel %d: Picture transmission complete. pkg_cnt:%d\r\n", channel, currentChannel->pkg_cnt - 1);
            currentChannel->send_pic_start = 0; // 停止图片发送
            currentChannel->WriteOneFrameEnd = -1;
            currentChannel->pkg_cnt = 1;
            return 0; // 传输完成
        }
        else if (currentChannel->VIDEO_FLAG == SEND_VIDEO) // 视频帧传输完成
        {
            xil_printf("Channel %d: Video frame complete. pkg_cnt:%d\r\n", channel, currentChannel->pkg_cnt - 1);
            currentChannel->WriteOneFrameEnd = -1;
            currentChannel->pkg_cnt = 1; // 重置计数
            return 0; // 传输完成
        }
    }

    return 0; // 继续传输
}


/**
 * @brief 主传输逻辑
 */
void lwip_video_transfer(void)
{
	MonitorAndExitAfterIterations();
    for (int i = 0; i < NUM_CHANNELS; i++) // 遍历所有通道
    {

        // 检查当前通道是否需要传输
        if (VdmaChannels[i].WriteOneFrameEnd >= 0)
        {
        	if (((VdmaChannels[i].VIDEO_FLAG == SEND_PIC && VdmaChannels[i].send_pic_start == 1) ||
        	     (VdmaChannels[i].VIDEO_FLAG == SEND_VIDEO && VdmaChannels[i].send_video_start == 1)))
            {
                // 调用通用传输逻辑处理
                if (handle_channel_transfer(i))
                {
                    continue; // 当前通道传输失败，跳过后续处理
                }
            }
            // 延迟，防止高频调用
//            usleep(10);
        }
    }
}


/*
 * Send frame data with udp
 *
 * @param pic is frame pointer will be send
 * @param piclen is frame length in one package
 * @param sn is Serial number for each ethernet package
 *
 * @format
 * @HeaderFormat
 *
 */

int sendpic(uint8_t *pic,  uint16_t piclen)
{
	if(client_pcb != NULL)
	{
		err_t err;

		/*  申请pbuf资源  */
		pbuf_to_be_sent = pbuf_alloc(PBUF_TRANSPORT, piclen + HEADER_SIZE, PBUF_POOL);
		if(pbuf_to_be_sent == NULL)
		{
			xil_printf("pbuf_alloc %d fail\n\r", piclen + HEADER_SIZE);
			return -3;
		}

		memcpy(pbuf_to_be_sent->payload, &packet_p, HEADER_SIZE);
		memcpy(pbuf_to_be_sent->payload+HEADER_SIZE, pic, piclen);

		pbuf_to_be_sent->len = HEADER_SIZE + piclen;
		pbuf_to_be_sent->tot_len = HEADER_SIZE + piclen;

//		err = udp_sendto(client_pcb, pbuf_to_be_sent, &target_addr, DIST_CONN_PORT);//发送到指定IP和端口
		err = udp_send(client_pcb,pbuf_to_be_sent);

		//发送报文
		 if (err != ERR_OK)
		{
			xil_printf("pbuf_to_be_sent->len %d\n\r", pbuf_to_be_sent->len);
			xil_printf(TXT_RED "Error on udp send : %d\r\n" TXT_RST, err);
			pbuf_free(pbuf_to_be_sent);
			return -2;
		}
		pbuf_free(pbuf_to_be_sent);
	}
	else
	{
		xil_printf("Error on client_pcb == NULL\r\n");
		return -1;
	}
	return 0;
}

#endif //#if defined (UDP_VIDEO)

#endif // UDP_COMMAND_SRV

#endif // XPAR_XEMACPS_NUM_INSTANCES || XPAR_XAXIETHERNET_NUM_INSTANCES

/*
usage:

call udp_server_setup() and platform_enable_interrupts() before the main_loop
call tcp_transfer_data() in the main_loop
run
```
    if (TcpFastTmrFlag) {
        tcp_fasttmr();
        TcpFastTmrFlag = 0;
    }
    if (TcpSlowTmrFlag) {
        tcp_slowtmr();
        TcpSlowTmrFlag = 0;
    }
```
in the main_loop, if tcp_transfer_data() not content it
keep a single `server_netif` definition, if you have more than one lwip process.

*/
